var slideStreamId = '';

var sign = {
        
    currentSlide: null,
    savePeriodical: null,
    width: null,
    height: null,
    modules: null,
    activeStack: [],
    allSlides: [],
    
    init : function(settings) {
        sign.config = {
            parent        : 'div#signContainer',
            baseUrl       : $('#baseUrl').val(),
            slideSelector : '.slide',
            saveTimer     : 30  // how often to push the module data back to the server
        };
        
        sign.modules = Array();
    
        // allow overriding the default config
        $.extend(sign.config, settings);
        
        sign.width  = screen.width;
        sign.height = screen.height;
        
        // set the container to be the resolution of the sign
        $(sign.config.parent).css({
            width: sign.width,
            height: sign.height
        });
        
                        
        // the periodical starts here, the * 1000 is because milliseconds are required
        sign.savePeriodical = window.setInterval(sign.save, sign.config.saveTimer * 1000);
    },
    
    registerSlideWithSign: function(obj) {
        obj.onDisplay();
    },
    
    getWidth: function() {
        return sign.width;
    },
    
    getHeight: function() {
        return sign.height;
    },
    
    loadData: function() {
        
        // get all the entities for the timeline
        $.ajax({
            url: sign.config.baseUrl + '/sign/index/get-data?slideStreamId=' + slideStreamId,
            type: 'GET',
            dataType: 'json',
            async: false,
            success: function(data, textStatus) {
                $.each(data, function(index, el) {
                                        
                    var newSlide = slide.createSlide(el);
                    
                    sign.allSlides.push(newSlide);
                });
            }
        });
        
        sign.queueActiveSlides();
        
        sign.start();
    },
    
    queueActiveSlides: function() {
        
        var funcExists = false;
        if ($.isFunction(scheduleModule.shouldBeDisplayed)) {
            funcExists = true;
        }
        
        $.each(sign.allSlides, function(index, el) {
            
            if (funcExists) {
                if (scheduleModule.shouldBeDisplayed(el) === true) {
                    sign.addSlideToActiveStack(el);
                }
                
            } else {
                sign.addSlideToActiveStack(newSlide);
            }
        });
        
        scheduleModule.resetCollectiveLength();
    },
    
    addSlideToActiveStack: function(newSlide) {
        
        sign.activeStack.push(newSlide);
    },
    
    start: function() {
        
        while (sign.activeStack.length) { 
            $(sign.config.parent).append(sign.activeStack.pop());
        }        
        
        $(sign.config.parent).cycle({
            fx: 'slideSpecific',     
            //easing: 'bounceout',  
            //fit: true,
            timeoutFn: sign.getTimeout
            //before: sign.before,
            //after: sign.after
        });
    },
    
    before: function(currentElement, nextElement, opts, isForward) {
        
        if (opts.nextSlide == opts.elements.length - 1) {
            
            //console.log('next slide is last, queuing next set of slides');
            
            sign.queueActiveSlides();
            
            if ($.isFunction(opts.addSlide)) {
                while (sign.activeStack.length) {
                    opts.addSlide(sign.activeStack.pop());
                }
            }
        }
        
        /*
        $.each(sign.modules, function(index, el) {
            if ($.isFunction(el.before)) {
                var result = el.before(currentElement, nextElement, opts, isForward);
            }
        });
        */
    },
    
    after: function(currentElement, nextElement, opts, isForward) {
        
        //var current = opts.elements[opts.currSlide];
        //$(current).prev().remove();
        
        /*
        $.each(sign.modules, function(index, el) {
            if ($.isFunction(el.after)) {
                el.after(currentElement, nextElement, opts, isForward);
            }
        });
        */
    },
    
    getTimeout: function(currentElement, nextElement, opts, isForward) {
        
        var current = opts.elements[opts.currSlide];
        var time = $(current).data('displayLength');
        return parseInt(time * 1000, 10);
    },
    
    getFx: function(opts) {
        var current = opts.elements[opts.currSlide];
        
        if ($.isFunction(transitionModule.getFx)) {
            return transitionModule.getFx($(current));
        }
    },
    
    save: function() {
        
    },
    
    registerModule: function(moduleObj) {
        sign.modules.push(moduleObj);
    }
};

$.fn.cycle.transitions.slideSpecific = function($cont, $slides, opts) {

    var fx = sign.getFx(opts);
    
    if ($.isFunction($.fn.cycle.transitions[fx])) {
        $.fn.cycle.transitions[fx]($cont, $slides, opts);
    } else {
        $.fn.cycle.transitions['none']($cont, $slides, opts);
    }    
};

var slide = {
        
    init : function(settings) {
    
        slide.config = {
            baseUrl: $('#baseUrl').val()
        };
    
        // allow overriding the default config
        $.extend(slide.config, settings);
    },
    
    createSlide: function(el) {
        
        var displayUrl = el.displayUrl;
    
        if (displayUrl === null) {
            displayUrl = slide.config.baseUrl + 
                '/sign/index/slide?slideId=' + el.data.slideId + 
                '&bbceScreenWidth=' + sign.getWidth() + 
                '&bbceScreenHeight=' + sign.getHeight();
        }

        var newSlide = $('<iframe></iframe>')
                        .attr('width', sign.getWidth() + 'px')
                        .attr('height', sign.getHeight() + 'px')
                        .attr('scrolling', 'no')
                        .attr('src', displayUrl)
                        .css({
                                border: '0',
                                margin: '0',
                                padding: '0'
                        })
                        .addClass('slide');
        
        newSlide.data('slideId', el.data.slideId);
        newSlide.data('title', el.data.title);
        newSlide.data('url', el.displayUrl);
        newSlide.data('displayLength', el.displayLength);
        
        // store the data for the modules into the object
        $.each(el.moduleData, function(name, data) {
            newSlide.data(name, data);
        });
        
        return newSlide;
    }
};


$(document).ready(function() {
    
    slideStreamId = $('input#slideStreamId').val();
    
    sign.init();
    slide.init();
    
    /**
     * Initialize the modules we want to use
     */
    scheduleModule.init();
    transitionModule.init();
    
    sign.loadData(); // load the slides after the interface has been setup and then start the slideshow
});


/**
 * Sets up the all the interaction for the schedule module
 */
var scheduleModule = {

    collectiveLength: 0,
        
    init : function(settings) {
    
        scheduleModule.config = {
            baseUrl      : $('#baseUrl').val(),
            moduleName   : 'Schedule'
        };
        
        $.extend(scheduleModule.config, settings);
        
        sign.registerModule(this);
    },
    
    before: function(currentElement, nextElement, opts, isForward) {
        var current = opts.elements[opts.currSlide];
        
        if ($(current).data('skipNext')) {
            $(current).data('skipNext', false);
            
            //console.log('Before: Current slide is: ' + opts.currSlide + ' : ' + $(current).data('title') + ' : skip next (' + $(current).data('skipNext') + ')');
            //console.log('Stopping slide show because next slide should be skipped');
            sign.stop();
            sign.start(opts.nextSlide + 1);
        }
    },
    
    after: function(currentElement, nextElement, opts, isForward) {
        var current = opts.elements[opts.currSlide];
        
        if (opts.nextSlide == 1 || opts.nextSlide == 2) {
            $(current).data('skipNext', true);
        }
        
        //console.log('After: Current slide is ' + opts.currSlide + ' : ' + $(current).data('title') + ' : skip next (' + $(current).data('skipNext') + ')');
    },
    
    resetCollectiveLength: function() {
        scheduleModule.collectiveLength = 0;
    },
    
    shouldBeDisplayed: function(slide) {
        var data = $(slide).data(scheduleModule.config.moduleName);
    
        var ts = Math.round(new Date().getTime() / 1000) + scheduleModule.collectiveLength;
        
        if ((data.length === 0) || (ts >= data.fromTimestamp && ts <= data.toTimestamp) || (ts >= data.fromTimestamp && data.toTimestamp === undefined) || (data.fromTimestamp === undefined && ts <= data.toTimestamp)) {
            //console.log($(slide).data('title') + ' should be displayed');
            scheduleModule.collectiveLength += $(slide).data('displayLength');
            return true;
        }    
        
        //console.log($(slide).data('title') + ' should not be displayed');
        return false;
    }
};

/**
 * Sets up the transition module
 */
var transitionModule = {

    init : function(settings) {
    
        transitionModule.config = {
            baseUrl      : $('#baseUrl').val(),
            moduleName   : 'Transition'
        };
        
        $.extend(transitionModule.config, settings);
        
        sign.registerModule(this);
    },
    
    getFx: function(obj) {
        return $(obj).data(transitionModule.config.moduleName).transition;
    }
};